package com.itheima.tlias.aop;

import com.alibaba.fastjson.JSON;
import com.itheima.tlias.mapper.OperateLogMapper;
import com.itheima.tlias.pojo.OperateLog;
import com.itheima.tlias.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

/**
 * @author
 * @version 1.0.1
 * @date 2023-04-13 15:43:21
 */
@Component
@Aspect
@Slf4j
public class LogAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OperateLogMapper operateLogMapper;

    @Pointcut("@annotation(com.itheima.tlias.annotation.Log)")
    public void pt() {
    }

    @Around("pt()")
    public Object insertLog(ProceedingJoinPoint proceedingJoinPoint) {

        String token = request.getHeader("token");
        if (token == null || "".equals(token)) {
            throw new RuntimeException("token非法");
        }
        try {
            Claims claims = JwtUtils.parseJWT(token);
            // 操作人
            Integer operateUser = (Integer) claims.get("id");
            // 操作时间
            LocalDateTime now = LocalDateTime.now();
            long start = System.currentTimeMillis();
            // 执行方法的全类名
            String className = proceedingJoinPoint.getTarget().getClass().getName();
            // 执行方法名
            String methodName = proceedingJoinPoint.getSignature().getName();
            // 方法运行时参数
            Object[] args = proceedingJoinPoint.getArgs();
            String methodParams = JSON.toJSONString(args);
            // 返回值
            Object result = proceedingJoinPoint.proceed();
            String returnValue = JSON.toJSONString(result);
            // 方法执行时长
            long end = System.currentTimeMillis();
            long costTime = end - start;

            OperateLog operateLog = new OperateLog();
            operateLog.setOperateUser(operateUser);
            operateLog.setOperateTime(now);
            operateLog.setClassName(className);
            operateLog.setMethodName(methodName);
            operateLog.setMethodParams(methodParams);
            operateLog.setReturnValue(returnValue);
            operateLog.setCostTime(costTime);
            operateLogMapper.insert(operateLog);
            return result;
        } catch (Throwable e) {
            e.printStackTrace();
            throw new RuntimeException("token过期");
        }
    }


}

